extends "../snippetTest.pkl"

import "pkl:yaml"

hidden parser: yaml.Parser = new { mode = "compat" }

examples {
  ["null"] {
    parser.parse("null")
    parser.parse("Null")
    parser.parse("NULL")
    parser.parse("NuLl") // never null
  }

  ["boolean"] {
    parser.parse("y")
    parser.parse("Y")
    parser.parse("yes")
    parser.parse("Yes")
    parser.parse("YES")
    parser.parse("YeS")   // never boolean
    parser.parse("n")
    parser.parse("N")
    parser.parse("no")
    parser.parse("No")
    parser.parse("NO")
    parser.parse("nO")    // never boolean
    parser.parse("true")
    parser.parse("True")
    parser.parse("TRUE")
    parser.parse("TrUe")  // never boolean
    parser.parse("false")
    parser.parse("False")
    parser.parse("FALSE")
    parser.parse("FaLsE") // never boolean
    parser.parse("on")
    parser.parse("On")
    parser.parse("ON")
    parser.parse("oN")    // never boolean
    parser.parse("off")
    parser.parse("Off")
    parser.parse("OFF")
    parser.parse("OfF")   // never boolean
  }

  ["int"] {
    parser.parse("123")
    parser.parse("-123")
    parser.parse("+123")
    parser.parse("0b1001")   // binary (1.1)
    parser.parse("-0b1001")  // neg. binary (1.1)
    parser.parse("+0b1001")  // pos. binary (1.1)
    parser.parse("0123")     // octal (1.1), decimal (1.2)
    parser.parse("-0123")    // neg. octal (1.1), neg. decimal (1.2)
    parser.parse("+0123")    // pos. octal (1.1), pos. decimal (1.2)
    parser.parse("0o123")    // octal (1.2)
    parser.parse("-0o123")   // never int
    parser.parse("+0o123")   // never int
    parser.parse("0x1A3")    // hexadecimal
    parser.parse("-0x1A3")   // neg. hexadecimal (1.1)
    parser.parse("+0x1A3")   // pos. hexadecimal (1.1)
    parser.parse("59:30:1")  // base 60 (1.1)
    parser.parse("-59:30:1") // neg. base 60 (1.1)
    parser.parse("+59:30:1") // pos. base 60 (1.1)
    parser.parse("1_2_3")    // separator (1.1)
  }
  
  ["float"] {
    parser.parse("123.456")
    parser.parse("0123.456")    // leading zero (1.2)
    parser.parse("-123.456")
    parser.parse("+123.456")
    parser.parse("123.456e2")
    parser.parse("123.456E2")
    parser.parse("123.456e-2")
    parser.parse("123.456E+2")
    parser.parse("-123.456e+2")
    parser.parse("+123.456E+2")
    parser.parse("59:30:1.234")  // base 60 (1.1)
    parser.parse("-59:30:1.234") // neg. base 60 (1.1)
    parser.parse("+59:30:1.234") // pos. base 60 (1.1)
    parser.parse("1_2_3.456")    // separator (1.1)
    parser.parse("1_2_3.4_5_6")  // separator (1.1 with our spec fix)
    parser.parse(".")            // zero (1.1, no revision/erratum exists)
    parser.parse(".___")         // zero (1.1 with our spec fix, no revision/erratum exists)
    
    parser.parse(".inf")
    parser.parse(".Inf")
    parser.parse(".INF")
    parser.parse(".InF")  // never float
    parser.parse("+.inf")
    parser.parse("+.Inf")
    parser.parse("+.INF")
    parser.parse("+.InF") // never float
    parser.parse("-.inf")
    parser.parse("-.Inf")
    parser.parse("-.INF")
    parser.parse("-.InF") // never float
    parser.parse(".nan")
    parser.parse(".NaN")
    parser.parse(".NAN")
    parser.parse(".nAn")  // never float
  }

  // parsed as string because Pkl doesn't have a timestamp type
  ["timestamp"] {
    parser.parse("2001-12-15T02:59:43.1Z")
    parser.parse("2011-11-18 19:00:59")
    parser.parse("!!timestamp 2001-12-15T02:59:43.1Z")
  }

  ["binary"] {
    parser.parse("!!binary AQID")
    parser.parse("!!binary 'AQID'")
    parser.parse("!!binary \"AQID\"")
    parser.parse("""
      !!binary |-
        AQID
        AQID
        AQID
      """)
  }

  ["string"] {
    // empty document is `null` according to YAML spec
    parser.parse("")
    parser.parse("   ")

    parser.parse("hello")
    parser.parse("hello\nworld")
    parser.parse("""
      hello
      world
      """)

    parser.parse("""
      x: |
        hello
        world
      """)

    parser.parse("""
      x: >
        hello
        world
      """)
  }

  ["sequence"] {
    parser.parse("""
      - one
      - two
      - three
      """)

    parser.parse("""
      !!set
      ? one
      ? two
      ? three
      """)
  }

  ["mapping"] {
    parser.parse("""
      name: Pigeon
      age: 42
      """)

    parser.parse("""
      ? - foo
        - bar
      : [one, two]
      """)
  }
  
  ["real-world example"] {
    // from: https://yaml.org/start.html
    parser.parse("""
      ---
      invoice: 34843
      date   : 2001-01-23
      bill-to: &id001
          given  : Chris
          family : Dumars
          address:
              lines: |
                  458 Walkman Dr.
                  Suite #292
              city    : Royal Oak
              state   : MI
              postal  : 48046
      ship-to: *id001
      product:
          - sku         : BL394D
            quantity    : 4
            description : Basketball
            price       : 450.00
          - sku         : BL4438H
            quantity    : 1
            description : Super Hoop
            price       : 2392.00
      tax  : 251.42
      total: 4443.52
      logo: !!binary AQID
      comments: >
          Late afternoon is best.
          Backup contact is Nancy
          Billsmer @ 338-4338.
      """)
  }

  ["invalid syntax"] {
    module.catch(() -> parser.parse("!@#$%"))
  }

  ["wrong tag/node combination"] {
    module.catch(() -> parser.parse("""
        !!set
        - one
        - two
        - three
        """))
  }
}
